/**
 * 一些全局的带功能性的公共东西 shareEvent,  定时器，scroll，懒加载 wxConfigInit，触摸效果，onTouchEnd，WPT.event
 */
import os from '@packages/lib-os';

import { getWebpSrc } from 'modules/image';

const shareEvent = (function se() {
    // 分享成功动作的回调
    let allShareEvent = {};
    $(window).on('wxShare:success', (e, data) => {
        Object.keys(allShareEvent).forEach((key) => {
            $.isFunction(allShareEvent[key]) && allShareEvent[key](e, data);
        });
    });

    function append(key, fun) {
        allShareEvent[key] = fun;
    }
    function clear(name) {
        if (name) {
            delete allShareEvent[name];
        } else {
            allShareEvent = {};
        }
    }
    return {
        append,
        clear,
    };
})();

// 定时器
const Interval = (function Interval() {
    let insterval = 0;
    let allData = {};
    function create() {
        if (!insterval) {
            insterval = window.setInterval(() => {
                Object.keys(allData).forEach((key) => {
                    if (allData[key]) {
                        $.isFunction(allData[key].callBack) && allData[key].callBack();
                    }
                });
            }, 1000);
        }
    }
    function append(key, fun, immediately) {
        allData[key] = { callBack: fun };
        if (immediately) $.isFunction(fun) && fun();
        create();
    }
    function clear(name) {
        //
        window.clearInterval(insterval);
        insterval = 0;
        if (name) {
            delete allData[name];
            !$.isEmptyObject(allData) && create();
        } else {
            allData = {};
        }
    }
    return {
        append,
        clear,
        allData,
    };
})();

function frequency(fn, fps = 60) {
    let time = 0;
    let now = time;
    let ST;
    const newFn = (...args) => {
        clearTimeout(ST);
        now = Date.now();
        const distance = now - time;

        if (distance >= fps) {
            time = now;
            fn(...args);
        } else {
            ST = setTimeout(() => {
                newFn(...args);
            }, distance);
        }
    };
    return newFn;
}

// window resize的时候触发scroll
$(window).on('resize', () => {
    $(window).trigger('scroll');
});

// 全局滚动事件
const scroll = (function scrollFn() {
    let allScroll = {};
    function createScroll() {
        $(window).on(
            'scroll.public',
            frequency(() => {
                const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
                Object.keys(allScroll).forEach((key) => {
                    $.isFunction(allScroll[key]) && allScroll[key](scrollTop);
                });
            })
        );
    }
    function appendScroll(key, callBack) {
        $.isEmptyObject(allScroll) && createScroll(); // 第一次加进来的时候创建
        allScroll[key] = callBack;
    }
    function clear(key) {
        // 有参数 清理对应的key  没有则清除定时器
        if (key) {
            delete allScroll[key];
        } else {
            allScroll = {};
        }
        $.isEmptyObject(allScroll) && $(window).off('scroll.public');
    }
    return {
        appendScroll,
        clear,
        allScroll,
    };
})();

// 懒加载
const initLazy = (function initLazyFn() {
    let imgArr = [];

    function inViewport(el, scrollTop) {
        const loadTop =
            scrollTop +
            (document.documentElement.clientHeight || document.body.clientHeight) +
            document.documentElement.clientHeight;
        const elTop = el.offset().top;
        const elHeight = el.innerHeight ? el.innerHeight() : el.offset().height;
        const elBto = el.offset().top + elHeight;
        const downTop = scrollTop - document.documentElement.clientHeight;
        return (elTop > scrollTop && elTop < loadTop) || (elBto > downTop && elTop < loadTop);
    }

    function imgLayout(_scrollTop) {
        $.each(imgArr, function eachFn(index, el) {
            const $el = $(el);
            const _src = $el.attr('data-original');
            if (el && _src) {
                const url = getWebpSrc(/^http|https|\/\//.test(_src) ? _src : `${WPT.CDNURL}${_src}`);
                if (inViewport($el, _scrollTop)) {
                    if (WPT.initLazy.onload) {
                        // 图片加载完后再处理， 建议 非等高图片纠正高度错误的时候可以用
                        console.log('lazy-onload');
                        const img = new Image();
                        img.src = url;
                        img.onload = function ($tager, src) {
                            if (WPT.Util.handelImgHeight(img.src) && WPT.Util.handelImgHeight(img.src) != img.height) {
                                $tager[0].style.height && ($tager[0].style.height = 'initial');
                            }
                            if (WPT.Util.handelImgHeight(img.src) == 0) {
                                $tager[0].style.height && ($tager[0].style.height = 'initial');
                            }
                            // if(WPT.Util.handelImgHeight(img.src)){
                            //    if(WPT.Util.handelImgHeight(img.src) != img.height){
                            //        $tager[0].style.height && ($tager[0].style.height = "initial");
                            //    }else{
                            //    }
                            // }else{
                            //    $tager[0].style.height && ($tager[0].style.height = "initial");
                            // }

                            if ($tager.hasClass('lazy')) {
                                if (!$tager.hasClass('backgroundImg')) {
                                    $tager.find('img').remove();
                                    $tager.find('i').remove();
                                    $tager.append(`<img src='${src}' />`);
                                } else {
                                    $tager.find('i').remove();
                                    $tager.css({ 'background-image': `url(${src}) ` });
                                    $tager.removeClass('backgroundImg');
                                }
                                $tager.removeClass('lazy');
                                $tager.removeClass('font-img');
                            }
                            // imgArr.splice(index, 0);
                        }.bind(this, $el, img.src);
                    } else if ($el.hasClass('lazy')) {
                        if (!$el.hasClass('backgroundImg')) {
                            $el.find('img').remove();
                            if ($el.find('i').hasClass('icon-circle-o')) {
                                $el.find('i').remove();
                            }
                            $el.append(`<img src='${url}' />`);
                        } else {
                            if ($el.find('i').hasClass('icon-circle-o')) {
                                $el.find('i').remove();
                            }
                            $el.css({ 'background-image': `url(${url}) ` });
                            $el.removeClass('backgroundImg');
                        }
                        $el.removeClass('lazy');
                        $el.removeClass('font-img');
                    }
                    // imgArr.splice(index, 0);
                }
            }
        });
    }
    /**
     *检测当前页面中存在需要加载项
     */
    function detection() {
        // var _self = this;
        imgArr = [];
        WPT.$curPage &&
            WPT.$curPage.find('.lazy').each(function () {
                const $el = $(this);
                // if ($el.attr("data-original")) {
                imgArr.push($el);
                // }
            });
    }

    const lazy = function (scrollTop) {
        scrollTop = scrollTop || document.documentElement.scrollTop || document.body.scrollTop;
        setTimeout(() => {
            detection();
            requestAnimationFrame(() => {
                imgLayout(scrollTop);
            });
        }, 100);
    };
    scroll.appendScroll('wall-lazy', lazy);
    return lazy;
})();

// 监听页面是否在滚动中
const onTouchEnd = (() => {
    WPT.isScroll = false;
    window.addEventListener('touchmove', () => {
        WPT.isScroll = true;
    });

    window.addEventListener('touchend', () => {
        // 页面开始滚动 or 不滚动
        setTimeout(() => {
            WPT.isScroll = false;
        }, 1);
    });

    // 移动端和pc端点击事件的兼容
    let touchEndTime = 0;
    // let isPhone = !(!$.os.phone || (window.webkit && window.webkit.messageHandlers)); // 非手机的话 用click
    // 没明白上面这个为啥要加window.webkit && window.webkit.messageHandlers
    let isPhone = os.phone;
    function touchEnd(callback, gapTime, touchEvent) {
        if (touchEvent && $.os.ios) {
            isPhone = true;
        }
        gapTime = gapTime || 100;
        if (isPhone) {
            let isValid = true;
            let time = 0;
            return {
                onTouchStart() {
                    isValid = true;
                    time = new Date().getTime();
                },
                onTouchMove() {
                    isValid = false;
                },
                onTouchEnd(e) {
                    //
                    if (WPT.isScroll) return;

                    const curTime = new Date().getTime();
                    if (curTime - touchEndTime < gapTime) {
                        return;
                    }
                    touchEndTime = curTime;
                    e.preventDefault();
                    e.stopPropagation();
                    // $.isFunction(callback) && callback(e);
                    isValid && new Date().getTime() - time < 200 && $.isFunction(callback) && callback(e);
                },
            };
        }
        return {
            onClick(e) {
                e.preventDefault();
                e.stopPropagation();
                const curTime = new Date().getTime();
                if (curTime - touchEndTime < 100) {
                    return;
                }
                touchEndTime = curTime;
                $.isFunction(callback) && callback(e);
            },
        };
    }
    return touchEnd;
})();

// 事件 touchend  和 click的使用
const event = (() => {
    // 需求： 移动端绑定touchend  pc端绑定click。
    const eventType = $.os.phone ? 'touchend' : 'click';
    function touchEnd(callback, e) {
        e.preventDefault();
        e.stopPropagation();
        callback(e);
    }
    function on(container, selector, data, fn, eventTriggerTime) {
        if (eventType == 'touchend') {
            if ($.isFunction(selector)) {
                selector = touchEnd.bind(null, selector);
            } else if ($.isFunction(data)) {
                data = touchEnd.bind(null, data);
            } else if ($.isFunction(fn)) {
                fn = touchEnd.bind(null, fn);
            } else {
                console.warn('an error parameters ');
            }
        }
        $(container).on(eventType, selector, data, fn, eventTriggerTime);
    }
    function one(container, selector, data, fn) {
        on(container, selector, data, fn, 1);
    }
    function off(container, selector, fn) {
        $(container).off(eventType, selector, fn);
        return this;
    }
    return {
        on,
        one,
        off,
    };
})();

WPT.logout =
    WPT.logout ||
    ((cb = {}) => {
        WPT.Modal.confirm('是否确认退出登录吗？', () => {
            if (os.device == 'web-pc') {
                const Api = WPT.Util.handleApi({
                    logoOut: '/v1.0/scanscope/logout', // 进入页面扫码
                });
                // pc scan logout
                WPT.getData(Api.logoOut, (data) => {
                    if (data.code == 0) {
                        cb.success && cb.success();
                        WPT.redirect('/');
                    }
                });
            } else if (os.device == 'web-phone') {
                // wap logout
                WPT.setCookie('userinfo_cookie', '', -1);
                cb.success && cb.success();
                WPT.redirect('/');
            }
        });
    });

WPT.scanRedirect = (url, cb) => {
    const Api = WPT.Util.handleApi({
        redirect: '/v1.0/scanscope/get-redirect-url', // 进入页面扫码
    });
    // pc scan redirect
    WPT.getData(Api.redirect, { url }, (res) => {
        if (res.code == 0) {
            if (cb) {
                $.isFunction(cb) && cb(res);
            } else {
                WPT.redirect(res.data.url);
            }
        }
    });
};

const pageChange = (function pageChangeFn() {
    // 分享成功动作的回调
    let allEvent = {};
    $(document)
        .off('Page:change')
        .on('Page:change', (_event, data) => {
            // 避免参数为空
            if (!data) {
                return;
            }
            const { url, router } = data;

            Object.keys(allEvent).forEach((key) => {
                $.isFunction(allEvent[key]) && allEvent[key](url, router);
            });
        });

    function append(key, fun) {
        allEvent[key] = fun;
    }
    function clear(name) {
        if (name) {
            delete allEvent[name];
        } else {
            allEvent = {};
        }
    }
    return {
        append,
        clear,
    };
})();

export { shareEvent, Interval, scroll, initLazy, onTouchEnd, event, os, pageChange };
